﻿module Mapparola.Client {

    export class Mapping {

        private _app: Mapparola.Client.App;
        private map: L.Map;
        private markerClusterGroup;
        private Markers: MapMarker[];

        private currentLocation: Position;

        constructor(app: Mapparola.Client.App) {

            this._app = app;
            this.Markers = [];

            //#region Mapping
            this.map = L.map($(".map").get(0));
            this.map.setView(<any>[51.505, -0.09], 1);

            L.Icon.Default.imagePath = "Styles/Images";

            L.tileLayer('http://a.tile.openstreetmap.org/{z}/{x}/{y}.png', {
                attribution: "Cacchina",
                id: 'gas12n.jo85b2im'
            }).addTo(this.map);

            this.markerClusterGroup = new (<any>L).MarkerClusterGroup();

            this.GetPosition((pos: Position) => {
                this.Center(pos.coords.longitude, pos.coords.latitude);
            });
        }

        public RefreshMap(): void {

            (<any>this.map)._onResize();
        }

        public Center(x: number, y: number, zoom?: number): void {

            var cen = L.latLng([y, x]);

            if (!zoom) {
                zoom = 13;
            }

            this.map.setView(cen, zoom,
                {
                    animate: true,

                });
        }

        public Zoom(zoom: number): void {

            this.map.setZoom(zoom);
        }

        public GetCurrentLocation(): Position {

            return this.currentLocation;
        }

        public GetCurrentPoint(): Core.Point {
            if (this.currentLocation) {
                return new Core.Point(this.currentLocation.coords.latitude, this.currentLocation.coords.longitude);
            }

        }

        public GetPosition(success: (pos: Position) => void, error?: (posErr: PositionError) => void) {
            
            if (geo_position_js.init()) {
                geo_position_js.getCurrentPosition(
                    //success
                    (pos: Position) => {
                        console.log(pos);
                        this.currentLocation = pos;
                        if (success) {
                            success(pos);
                        }

                    },
                    //error
                    (posError: PositionError) => {
                        console.log(posError);
                        if (error) {
                            error(posError);
                        }
                    });
            }
            else {
                alert("Functionality not available");
            }
        }

        public AddMarker(coords: L.LatLng, options: L.MarkerOptions, text?: string): MapMarker {

            var marker = new L.Marker(coords, options);

            if (text) {
                marker.bindPopup(text);
            }

            this.markerClusterGroup.addLayer(marker);

            var mapMarker: MapMarker = {
                Marker: marker,
                Token: this._app.CreateGUID()
            };

            this.Markers.push(mapMarker);

            return mapMarker;
        }

        public RemoveMarkerByToken(token: string): void {

            this.Markers = this.Markers.filter((value: MapMarker) => {
                if (value.Token === token) {
                    return true;
                }
            });
        }

        public RemoveAllMarkers(): void {

            this.Markers.forEach((value: MapMarker) => {
                this.markerClusterGroup.removeLayer(value.Marker);
            });

            this.Markers = [];
        }

        public RenderMessages(discussions: Mapparola.Core.Client.DiscussionC[]): void {
            
            var text: string
            var discussion: Core.Client.DiscussionC;

            this._app.Mapping.RemoveAllMarkers();

            for (var i = 0; i < discussions.length; i++) {
                discussion = discussions[i];
                
                text = discussion.GetText();

                //Create a lat/lng object
                var latLngObj = new L.LatLng(discussion.Location.y, discussion.Location.x);

                //Add marker to cluster layer
                var marker = this.AddMarker(
                    latLngObj,
                    {
                        title: text
                    },
                    text);

            }

            //Show cluster layer
            this.map.addLayer(this.markerClusterGroup);
        }

    }

    export interface MapMarker {
        Token: string;
        Marker: L.Marker;
    }
}